<template>
  <div class="markdown-editor">
    <div class="editor-header">
      <h2 class="title">Markdown 编辑器</h2>
      <div class="toolbar">
        <el-button-group>
          <el-button :type="mode === 'wysiwyg' ? 'primary' : 'default'" @click="switchMode('wysiwyg')" size="small">
            所见即所得
          </el-button>
          <el-button :type="mode === 'markdown' ? 'primary' : 'default'" @click="switchMode('markdown')" size="small">
            Markdown
          </el-button>
        </el-button-group>

        <div class="action-buttons">
          <el-button @click="importFile" size="small" plain>
            <el-icon>
              <FolderOpened />
            </el-icon>
            导入
          </el-button>
          <el-button @click="exportMarkdown" size="small" plain>
            <el-icon>
              <Download />
            </el-icon>
            导出 MD
          </el-button>
          <el-button @click="exportHtml" size="small" plain>
            <el-icon>
              <Document />
            </el-icon>
            导出 HTML
          </el-button>
          <el-button @click="clearContent" size="small" plain type="danger">
            <el-icon>
              <Delete />
            </el-icon>
            清空
          </el-button>
        </div>
      </div>
    </div>

    <div class="editor-container">
      <div ref="editorElement" class="editor-content"></div>
    </div>

    <div class="editor-footer">
      <div class="status-info">
        <span>字符数: {{ charCount }}</span>
        <span>单词数: {{ wordCount }}</span>
        <span>行数: {{ lineCount }}</span>
      </div>
      <div class="editor-info">
        <span>当前模式: {{ mode === 'wysiwyg' ? '所见即所得' : 'Markdown' }}</span>
      </div>
    </div>

    <!-- 隐藏的文件输入 -->
    <input ref="fileInput" type="file" accept=".md,.markdown,.txt" @change="handleFileImport" style="display: none" />
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, computed } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { FolderOpened, Download, Document, Delete } from '@element-plus/icons-vue'
import { marked } from 'marked'

// 组件名称
defineOptions({
  name: 'MarkdownEditor'
})

// 响应式数据
const editorElement = ref<HTMLElement>()
const fileInput = ref<HTMLInputElement>()
const mode = ref<'wysiwyg' | 'markdown'>('wysiwyg')
const content = ref<string>('')
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const editor = ref<any>(null)

// 计算属性
const charCount = computed(() => {
  return content.value.length
})

const wordCount = computed(() => {
  return content.value.trim() ? content.value.trim().split(/\s+/).length : 0
})

const lineCount = computed(() => {
  return content.value ? content.value.split('\n').length : 1
})

// 初始化编辑器
const initEditor = async () => {
  if (!editorElement.value) return

  try {
    // 动态导入编辑器和样式
    const [{ default: Editor }] = await Promise.all([
      import('@toast-ui/editor'),
      import('@toast-ui/editor/dist/toastui-editor.css')
    ])

    editor.value = new Editor({
      el: editorElement.value,
      height: '500px',
      initialEditType: 'wysiwyg',
      previewStyle: 'vertical',
      placeholder: '请输入 Markdown 内容...',
      initialValue: getDefaultContent(),
      toolbarItems: [
        ['heading', 'bold', 'italic', 'strike'],
        ['hr', 'quote'],
        ['ul', 'ol', 'task', 'indent', 'outdent'],
        ['table', 'image', 'link'],
        ['code', 'codeblock'],
        ['scrollSync']
      ],
      events: {
        change: () => {
          if (editor.value) {
            content.value = editor.value.getMarkdown()
          }
        }
      },
      theme: 'default'
    })

    // 初始化内容
    content.value = editor.value.getMarkdown()
  } catch (error) {
    console.error('编辑器初始化失败:', error)
    ElMessage.error('编辑器初始化失败')
  }
}

// 默认内容
const getDefaultContent = (): string => {
  return `# 欢迎使用 Markdown 编辑器

这是一个功能强大的 Markdown 所见即所得编辑器。

## 主要功能

- **所见即所得编辑**: 实时预览编辑效果
- **Markdown 模式**: 原生 Markdown 语法编辑
- **文件导入导出**: 支持 .md 文件导入和导出
- **HTML 导出**: 将 Markdown 转换为 HTML 格式

## 使用指南

### 1. 文本格式化

你可以使用以下格式：

- **加粗**: **加粗文本**
- *斜体*: *斜体文本*
- ~~删除线~~: ~~删除文本~~
- \\\`代码\\\`: \\\`行内代码\\\`

### 2. 列表

#### 无序列表
- 项目 1
- 项目 2
- 项目 3

#### 有序列表
1. 第一项
2. 第二项
3. 第三项

### 3. 代码块

\\\`\\\`\\\`javascript
function hello() {
  console.log('Hello, Markdown!');
}
\\\`\\\`\\\`

### 4. 表格

| 功能 | 状态 | 说明 |
|------|------|------|
| 编辑 | ✓ | 支持所见即所得 |
| 预览 | ✓ | 实时预览 |
| 导出 | ✓ | 支持多种格式 |

### 5. 引用

> 这是一个引用块。
> 可以包含多行内容。

---

**开始你的 Markdown 创作之旅吧！**`
}

// 切换模式
const switchMode = (newMode: 'wysiwyg' | 'markdown') => {
  if (!editor.value) return

  mode.value = newMode
  editor.value.changeMode(newMode)

  ElMessage.success(`已切换到${newMode === 'wysiwyg' ? '所见即所得' : 'Markdown'}模式`)
}

// 导入文件
const importFile = () => {
  fileInput.value?.click()
}

// 处理文件导入
const handleFileImport = (event: Event) => {
  const target = event.target as HTMLInputElement
  const file = target.files?.[0]

  if (!file) return

  const reader = new FileReader()
  reader.onload = (e) => {
    const content = e.target?.result as string
    if (editor.value) {
      editor.value.setMarkdown(content)
      ElMessage.success('文件导入成功')
    }
  }

  reader.onerror = () => {
    ElMessage.error('文件读取失败')
  }

  reader.readAsText(file, 'UTF-8')

  // 清空 input
  target.value = ''
}

// 导出 Markdown
const exportMarkdown = () => {
  if (!editor.value) return

  const markdown = editor.value.getMarkdown()
  const blob = new Blob([markdown], { type: 'text/markdown;charset=utf-8' })
  const url = URL.createObjectURL(blob)
  const link = document.createElement('a')

  link.href = url
  link.download = `markdown-${Date.now()}.md`
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)

  URL.revokeObjectURL(url)
  ElMessage.success('Markdown 文件已下载')
}

// 导出 HTML
const exportHtml = async () => {
  if (!editor.value) return

  const markdown = editor.value.getMarkdown()
  const html = await marked(markdown)

  const fullHtml = `<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Markdown Export</title>
  <style>
    body {
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
      line-height: 1.6;
      color: #333;
      max-width: 800px;
      margin: 0 auto;
      padding: 20px;
    }
    h1, h2, h3, h4, h5, h6 {
      margin-top: 24px;
      margin-bottom: 16px;
      font-weight: 600;
      line-height: 1.25;
    }
    h1 { font-size: 2em; border-bottom: 1px solid #eaecef; padding-bottom: 10px; }
    h2 { font-size: 1.5em; }
    h3 { font-size: 1.25em; }
    code {
      background: #f6f8fa;
      border-radius: 3px;
      padding: 2px 4px;
      font-size: 85%;
    }
    pre {
      background: #f6f8fa;
      border-radius: 6px;
      padding: 16px;
      overflow: auto;
    }
    blockquote {
      border-left: 4px solid #dfe2e5;
      padding-left: 16px;
      color: #6a737d;
    }
    table {
      border-collapse: collapse;
      width: 100%;
      margin: 16px 0;
    }
    th, td {
      border: 1px solid #dfe2e5;
      padding: 8px 12px;
      text-align: left;
    }
    th {
      background: #f6f8fa;
      font-weight: 600;
    }
  </style>
</head>
<body>
${html}
</body>
</html>`

  const blob = new Blob([fullHtml], { type: 'text/html;charset=utf-8' })
  const url = URL.createObjectURL(blob)
  const link = document.createElement('a')

  link.href = url
  link.download = `markdown-${Date.now()}.html`
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)

  URL.revokeObjectURL(url)
  ElMessage.success('HTML 文件已下载')
}

// 清空内容
const clearContent = async () => {
  try {
    await ElMessageBox.confirm(
      '确定要清空所有内容吗？此操作不可恢复。',
      '确认清空',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }
    )

    if (editor.value) {
      editor.value.setMarkdown('')
      ElMessage.success('内容已清空')
    }
  } catch {
    // 用户取消操作
  }
}

// 生命周期
onMounted(() => {
  initEditor()
})

onBeforeUnmount(() => {
  if (editor.value) {
    editor.value.destroy()
  }
})
</script>

<style scoped>
.markdown-editor {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
  height: calc(100vh - 40px);
  display: flex;
  flex-direction: column;
}

.editor-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding-bottom: 15px;
  border-bottom: 1px solid #ebeef5;
}

.title {
  color: #303133;
  margin: 0;
  font-size: 1.5rem;
  font-weight: 600;
}

.toolbar {
  display: flex;
  align-items: center;
  gap: 20px;
}

.action-buttons {
  display: flex;
  gap: 10px;
}

.editor-container {
  flex: 1;
  border: 1px solid #ebeef5;
  border-radius: 8px;
  overflow: hidden;
}

.editor-content {
  height: 100%;
}

.editor-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 15px;
  padding-top: 15px;
  border-top: 1px solid #ebeef5;
  font-size: 12px;
  color: #909399;
}

.status-info {
  display: flex;
  gap: 20px;
}

.editor-info {
  font-weight: 500;
}

/* Toast UI Editor 样式覆盖 */
:deep(.toastui-editor-defaultUI) {
  border: none;
}

:deep(.toastui-editor-main-container) {
  background: #fff;
}

:deep(.toastui-editor-toolbar) {
  background: #f8f9fa;
  border-bottom: 1px solid #ebeef5;
  padding: 8px 16px;
}

:deep(.toastui-editor-toolbar-group) {
  margin-right: 12px;
}

:deep(.toastui-editor-toolbar-icons) {
  color: #606266;
  border-radius: 4px;
  padding: 4px;
  transition: all 0.2s;
}

:deep(.toastui-editor-toolbar-icons:hover) {
  background: #e1f3ff;
  color: #409eff;
}

:deep(.toastui-editor-md-container),
:deep(.toastui-editor-ww-container) {
  background: #fff;
}

:deep(.toastui-editor-md-code-block-line-background),
:deep(.toastui-editor-ww-code-block-line-background) {
  background: #f6f8fa;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .markdown-editor {
    padding: 15px;
  }

  .editor-header {
    flex-direction: column;
    align-items: stretch;
    gap: 15px;
  }

  .toolbar {
    flex-direction: column;
    gap: 15px;
  }

  .action-buttons {
    flex-wrap: wrap;
    justify-content: center;
  }

  .editor-footer {
    flex-direction: column;
    gap: 10px;
    text-align: center;
  }

  .status-info {
    justify-content: center;
  }
}

@media (max-width: 480px) {
  .title {
    font-size: 1.2rem;
    text-align: center;
  }

  .action-buttons {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 8px;
  }
}
</style>
